Targeted Spells: migrate borders onto DF.Border (+ engine fixes)#164
Open
Krathe82 wants to merge 34 commits into
Open
Targeted Spells: migrate borders onto DF.Border (+ engine fixes)#164Krathe82 wants to merge 34 commits into
Krathe82 wants to merge 34 commits into
Conversation
Migrate the group per-icon base border off the 4 hand-rolled edge textures
(icon.borderLeft/Right/Top/Bottom) onto the unified DF.Border backend, matching
Personal Targeted Spell / Targeted List and the rest of the Stage 4.x borders.
Create path now allocates iconFrame.border = DF.Border:New(iconFrame); the
per-update ApplyIconSettings drives BuildSpec(db, "targetedSpell", {iconMode})
+ Apply (spec.enabled = showBorder, spec.size = the pixel-perfect thickness),
and insets the icon art + cooldown swipe by that thickness when shown. Reads the
existing targetedSpell* keys, so the current GUI works unchanged; the full
border toolkit (style/alpha/gradient/inset/animation) is now available for a
later CreateBorderControls GUI pass.
The "important spell" highlight is untouched in this stage (Stage 2).
Retire the bespoke important-spell highlight (InitGlow/Solid/AnimatedBorder + the marching-ants animator + pulse AnimationGroup) in the live render path, replacing it with a second DF.Border overlay on the existing highlightFrame. The highlightFrame stays as the secret-safe alpha gate (SetAlphaFromBoolean on the possibly-secret IsSpellImportant result); only its border content moves to DF.Border. The highlightStyle enum is preserved (no saved migration) and mapped at render time onto a DF.Border animation: glow→PROC, marchingAnts→DF_DASH, pulse→ DF_PULSATE, solidBorder→static SOLID. Both render sites (group + personal) and both create paths now allocate/drive iconFrame.highlightBorder / icon.highlightBorder. The bespoke Init/Update/Hide helpers stay defined for now — TestMode's preview still calls them; they migrate + get deleted in Stage 3. Teardown calls on them are safe no-ops (the new overlay hides with its container).
…ers (Stage 3a)
TestMode's targeted-spell preview highlight now uses the same DF.Border overlay
+ style→animation mapping as the live path (overlay lazily allocated on the
preview highlightFrame). The active-icon teardown drops its bespoke
HideAnimated/SolidBorder + TargetedSpellAnimator calls for a single
DF.Border:Apply{enabled=false}.
Nothing now references the bespoke Init/Update/Hide Glow/Solid/Animated helpers,
the marching-ants TargetedSpellAnimator driver, or InitPulseAnimation — they are
dead code, deleted in Stage 3b. (Highlights.lua / Dispel.lua have their own
unrelated InitAnimatedBorder / pulseAnim and are untouched.)
Swap the bare Show Border / Size / Colour controls for GUI:CreateBorderControls, matching the Personal Targeted Spell sibling: adds Style (Solid/Gradient), Border Alpha, Inset, Blend Mode, Shadow and Animate. (Class/Role colour is deliberately not included — consistent with the siblings and not meaningful for "an enemy casting at this unit".) The render path already reads every targetedSpell* border key via BuildSpec, so the controls light up the engine with no render change. The now-unused base-border keys keep working as the Show Border + Size + Colour the control still exposes.
…r (Stage 3b) The bar highlight (bar.highlightFrame glow via DF.UpdateGlowBorder) now uses a DF.Border overlay with the PROC animation, matching the icon highlight. Both live sites (render + the light colour-update path) and the TestMode teardown are migrated. With this, NOTHING references the bespoke Init/Update/Hide helpers or the TargetedSpellAnimator driver — they are fully dead and ready to delete.
Remove the entire "HIGHLIGHT STYLE ANIMATIONS" block (~346 lines): the
TargetedSpellAnimator marching-ants/pulse OnUpdate driver, InitAnimatedBorder/
InitSolidBorder/InitGlowBorder (+ Update/Hide) and InitPulseAnimation, plus
their DF.* exports and the DASH/ANIM tunables — all superseded by DF.Border.
Also converts three remaining icon-teardown sites (which called the helpers by
their bare local names — missed by the earlier DF.*-only grep) to a single
DF.Border:Apply{enabled=false}. Highlights.lua / Dispel.lua keep their own
unrelated InitAnimatedBorder / pulseAnim and are untouched.
Targeted Spells borders (base + important highlight, on icons, personal frame,
the Targeted List bar, and test mode) now run entirely through DF.Border.
Stage 1.5 exposed the full DF.Border toolkit for the targetedSpell border but the new keys were never defaulted, so Border Blend Mode / Animation (and Style / Gradient / Inset / Shadow / Texture) read nil and the dropdowns showed the literal "nil". Add the full targetedSpellBorder* default set to both party and raid, mirroring the personalTargetedSpell sibling (AnimationType="NONE", BlendMode="BLEND", Style="SOLID", etc.).
Seed the full targetedSpellImportantBorder* key set (party + raid) for the
upcoming 'Important Spell Border' subsection — a second DF.Border gated by the
Highlight Important Spells toggle, replacing the bespoke highlightStyle enum.
Seeded from the old highlight values (Colour {1,0.8,0}, Size 3, Inset 2) with
AnimationType=PROC (old default style 'glow'). Keys are inert until the render
+ GUI + migration land.
…rder keys DF:MigrateTargetedSpellImportantBorder (Core.lua, per-profile guard _tsImportantBorderV1; called at login + profile switch) copies any customised targetedSpellHighlightColor/Size/Inset/Style into the new targetedSpellImportantBorder* keys, mapping style->animation (glow=PROC, marchingAnts=DF_DASH, pulse=DF_PULSATE, solidBorder/none=NONE). Additive + no-op for default profiles (defaults already match); does not change rendering yet.
…er subsection
Switch the group per-icon important-spell highlight render to a full
DF.Border via BuildSpec(db, "targetedSpellImportant", {iconMode}) and
swap the GUI from the bare Style/Colour/Size/Inset controls to
CreateBorderControls. The highlight border now exposes the whole border
toolkit (style, alpha, inset, blend mode, gradient, shadow, animation),
gated by the existing Highlight Important Spells toggle + the secret-safe
SetAlphaFromBoolean(isImportant). Frame offset now follows the
targetedSpellImportant border size/inset. Personal Targeted Spell still
uses the prior style->animation mapping (its render block is shared and
reads a different key prefix).
…ggle Test mode (Bug 1): the base border still drew the old 4 edge textures (icon.borderLeft/Right/Top/Bottom), which the live create path retired when it moved to DF.Border, so no border rendered in test mode. Render it through DF.Border (lazy-allocated icon.border + BuildSpec) mirroring live ApplyIconSettings, and migrate the test-mode important highlight onto the targetedSpellImportant* keys so test mode is WYSIWYG with the new GUI. Highlight toggle (Bug 2): CreateBorderControls always added its own Show Border checkbox, so the Important Spells section had two competing gates (Highlight Important Spells + Show Border) — the animation, gated only by the master toggle, kept showing when Show Border was unchecked while the toolkit hid. Add opts.noShowToggle to suppress the built-in checkbox and let the Highlight Important Spells master be the single gate.
…OC glow The bar highlight migration hardcoded a PROC (LibCustomGlow ProcGlow) animation on top of the solid highlight border, so the Targeted List important highlight flashed/animated where it used to be a calm glow. The Targeted List highlight exposes only an enable toggle + colour (no animation control), so drop the animation and render a plain static solid border in the highlight colour at both apply sites (render + lightweight colour update).
Enable alpha on the Highlight Color picker and honour color.a in the highlight border render (was hardcoded a=1) so the static highlight can be made translucent. Default + reset colour now carry a=1.
The highlight frame offset subtracted the inset (offset = borderSize + hlSize - hlInset) while BuildSpec ALSO applies the inset via spec.inset in iconMode, so the Border Inset slider was applied twice and resized the frame, throwing off centring. Make the frame offset inset-independent (borderSize + hlSize) and let the engine's symmetric spec.inset own the inset, at both the live and test-mode render sites.
…border) The Important Spell Border thickness slider had sizeMin=1, so it couldn't be set to 0 like the base border (sizeMin=0). Lower to 0; at 0 the solid edges vanish while any configured animation keeps running, consistent with every other DF.Border (thickness and animation are independent; animation is gated by the border being shown, not by thickness).
… the Border group Both pages parked an icon Alpha slider and a cooldown-swipe toggle under the Border header, ahead of CreateBorderControls — so the Border group mixed feature display knobs with the shared engine, and the icon Alpha sat confusingly next to the engine's own Border Alpha. Move both into the top-level Settings group (matches Defensive Icon, where Hide Cooldown Swipe already lives in Settings). The Border header is now purely the shared DF.Border toolkit on every migrated page.
Apply() always Show()'d the four edge textures in SOLID/GRADIENT mode; at size 0 they collapse to zero width/height but a degenerate texture could still leave a hairline. Other borders never exposed this (their sliders min at 1) but the Targeted Spells base + important borders now allow 0. Hide the edges when size <= 0 so 0 means no visible border, engine-wide. Animation overlays are separate frames and keep running, consistent with thickness being independent of animation.
Texture-style borders clamped edgeSize to 1px at size 0 instead of hiding, so thickness 0 still showed a 1px textured border — inconsistent with the solid/gradient path which now hides at 0. Hide the backdrop when size <= 0 so any border style means no border at 0. Animation overlays are applied later in Apply gated only on spec.animation, so they keep running at thickness 0 regardless of style.
…ubsection
Brings the Personal Targeted Spell important-spell highlight to parity with
the group/party side: render switches to BuildSpec(db,
"personalTargetedSpellImportant", {iconMode}) with an inset-independent
frame offset, the GUI swaps the old Style/Colour/Size/Inset controls for
CreateBorderControls (noShowToggle; the Highlight Important Spells toggle is
the single gate), full personalTargetedSpellImportantBorder* Config defaults
seeded in both tables, and the migration maps the old
personalTargetedSpellHighlight* keys across under an independent guard so
profiles already through the group step still migrate personal.
Missing Buff and Personal Targeted Spell borders are animation-capable but clamped sizeMin to 1, so you couldn't run an animation with no solid edge (every other animation-capable border already allows 0: buff, debuff, defensive, targeted spell + important). Lower both to sizeMin 0. Safe now that Apply hides the edges at 0 while the animation keeps running. Non- animation borders (pet, resource bar, targeted list) stay at 1 — 0 there would just duplicate the Show Border toggle.
StartAnimation started the LCG glow (PULSATE/CHASE/FLASH/PROC) immediately when animRect:GetWidth() was non-zero, only deferring on an exact 0. But a frame resized during the same layout pass (e.g. a test-mode enable toggle re-render) reports a stale/unresolved non-zero width, so the glow sized to the wrong (too-large) rect on alternate re-renders. Always defer the start to the next frame so it reads the settled size; the start token still guards against a superseded or stopped start, and one frame of latency is imperceptible.
PROC was started with startAnim=true, playing LCG's proc start animation (begins large, shrinks to the border). DF.Border uses PROC as a CONTINUOUS border animation, so that start flash re-fired on every re-Apply (test-mode toggles, relayouts); when the prior start animation hadn't fully torn down, two glows rendered at two sizes (one inset, one further out) — visible as the highlight flashing/doubling on alternate toggles. Start straight in the loop state (startAnim=false) for a clean, stable glow with no flash-in. Also reverts the always-defer glow-start change from the prior commit: it did not address this and is unnecessary; restore the original defer-only-when-unsized behaviour.
Replaces the hardcoded startAnim with a per-border setting (<prefix>BorderAnimationProcStart, default off). BuildSpec reads it into anim.procStart, StartAnimation passes it to ProcGlow_Start, and animSpecHash includes it so toggling re-applies cleanly. CreateBorderControls gains a 'Proc Start Flash' checkbox shown only when Animation = PROC. Default off keeps the clean continuous glow (no flash-in, no doubling on re-apply). Users who want the proc flash can opt in per border; it plays cleanly on a normal single appearance — only rapid re-toggling (a test-mode stress, not real play) can still double it, which is inherent to using a one-shot proc effect as a continuous animation.
Logs each ProcGlow start (target, pre-existing glow + its ProcStart/ProcLoop shown state, procStart flag) and each stop (which frame still carries a glow) to chat when debug mode is on. Lets us see, on one slow toggle cycle, whether the double is two starts without a stop, a second glow on a new target, or one frame with both textures shown. To be reverted once the root cause is identified.
Diagnosis from runtime logs: DF's start/stop reference lifecycle is clean (every start sees existing=nil, every stop releases the glow), so the double was NOT an orphaned frame. The glow frame carries two textures — ProcStart (the big ~3.5x start-flash) and ProcLoop (the small loop). LCG's pool resetter hides the frame and clears the reference but leaves those textures' shown/alpha state, so a frame re-acquired from the shared pool could return with BOTH visible: the inset + further-out double seen on alternate re-applies. Fix: in stopAll, before LCG releases the frame, stop its ProcStart/ProcLoop animation groups and hide+zero both textures, so the next Acquire starts clean. Keeps the proc start flash working (no need to disable it).
Root cause confirmed and fixed (texture reset on pool release). Strip the debug prints added for diagnosis.
The new fingerprint Targeted Spells icons and the Personal Targeted display auto-showed in test mode whenever their feature was enabled, with no test- panel switch (the old 'Targeted Spell' checkbox slot was repurposed for Targeted List after Blizzard killed the old display). Add proper toggles: - testShowTargetedSpell (repurposes the pre-existing dead key, now default true) + new testShowPersonalTargeted, in both party + raid config tables. - Two checkboxes in the test panel's Indicators section, both refreshing via UpdateAllTestTargetedSpell (which drives both previews). - Render gates in UpdateAllTestTargetedSpell: icons + personal now respect their toggle (off => hidden, via the existing else-branch hide path). - Wired into all four presets (Static/Combat/Healer/Full), mirroring Targeted List (off in Static/Combat, on in Healer/Full). Default true preserves the prior auto-show behaviour until a preset/toggle changes it.
… with Duration Match the buff/debuff convention — Alpha belongs with Icon Size + Scale, and the cooldown swipe sits with the duration settings — rather than parked in the functional Settings group. Both the Targeted Spells and Personal Targeted pages. The swipe stays enabled independent of the duration text (it's the radial cooldown sweep, not the numeric text).
…ttings MigrateTargetedSpellImportantBorder's mapHighlight guarded each copy on the new …ImportantBorder* key being nil, but the ADDON_LOADED default-merge populates those keys before the migration runs, so the guard never fired and existing Highlight settings never carried into the new keys. Gate solely on the per-profile _tsImportantBorderV1 / _personalTsImportantBorderV1 flags (one run) and copy the old values unconditionally, mirroring MigrateBorderInsetFold.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrates the Targeted Spells, Personal Targeted Spells, and Targeted List borders onto the shared DF.Border engine, and folds in the border-engine fixes that this work surfaced.
Targeted Spells / Personal Targeted
Targeted List
DF.Border engine fixes (surfaced here, benefit every border consumer)
Note: no changelog entry yet — happy to add one.